package demo7;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 姚东名
 * Date: 2024-06-13
 * Time: 12:44
 */
/*
7. static成员
 */
class Student {
    public String name;//姓名
    public String gender;//性别
    public int age;//年龄
    public double score;//分数
    public static String classRoom = "113";

    public Student(String name, String gender, int age, double score) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.score = score;
    }
}
/*public class Students1 {
    //7.1再谈学生类
    //使用前文中介绍的学生类实例化三个对象s1、s2、s3，每个对象都有自己特有的名字、性别，年龄，学分绩点等成
    //员信息，这些信息就是对不同学生来进行描述的，如下所示：
    public static void main(String[] args) {
        Student s1 = new Student("zhangsan", "男", 19, 8.8);
        Student s2 = new Student("lisi", "男", 28, 4.5);
        Student s3 = new Student("huangwu", "女", 15, 5.5);
    }
}*/
/*
假设三个同学是同一个班的，那么他们上课肯定是在同一个教室，那既然在同一个教室，那能否给类中再加一个成
员变量，来保存同学上课时的教室呢？答案是不行的。

之前在Student类中定义的成员变量，每个对象中都会包含一份(称之为实例变量)，因为需要使用这些信息来描述
具体的学生。而现在要表示学生上课的教室，这个教室的属性并不需要每个学生对象中都存储一份，而是需要让所
有的学生来共享。在Java中，被static修饰的成员，被称为静态成员，也可称为类成员，其不属于某个具体的对象，是所有对象共享的。
 */

//7.2static修饰成员变量
/*
static修饰的成员变量，称为静态成员变量，静态成员变量最大的特点：不属于某个具体的对象，是所有对象所共享的。
【静态成员变量特性】
1. 不属于某个具体的对象，是类的属性，所有对象共享的，不储存某个对象的空间
2. 既可以通过对象访问，也可以通过类名访问，但是一般更推荐使用类名访问
3. 类变量存储在方法区中
4. 生命周期伴随类的一生(随类的加载而创建，随类的卸载而销毁)
 */
public class Students {
    public static void main2(String[] args) {
        System.out.println(Student.classRoom);
    }

    //编译失败：
    // java: classRoom 在 demo7.Student 中是 private 访问控制
    public static void main(String[] args) {
        //静态成员变量可以直接通过类名来访问
        System.out.println(Student.classRoom);
        Student s1 = new Student("zhangsan", "男", 19, 8.8);
        Student s2 = new Student("lisi", "男", 28, 4.5);
        Student s3 = new Student("huangwu", "女", 15, 5.5);

        //也可以通过对象访问：但是classRoom是三个对象共享的
        System.out.println(s1.classRoom);
        System.out.println(s2.classRoom);
        System.out.println(s3.classRoom);
    }
}

//7.3static修饰成员方法
//一般类中的数据成员都设置为private，而成员方法设置为public，那设置之后，Student类中classRoom属性如何
//在类外访问呢？

//Java中，被static修饰的成员方法成为静态成员方法，是类的方法，不是个类所持有的。静态成员一般是通过静态方法来访问的。

/*
【静态方法特征】
1. 不属于某个对象的，是类方法
2. 可以通过对象调用，也可以通过类名.静态方法名(...)式调用，更推荐后者
3. 不能在静态方法中访问任何静态成员变量
public static String getClassRoom(){
System.out.println(this);
return classRoom;
}

// 编译失败：Error:(35, 28) java: 无法从静态上下文中引用非静态 变量 this

public static String getClassRoom(){
age += 1;
return classRoom;
}

// 编译失败：Error:(35, 9) java: 无法从静态上下文中引用非静态 变量 age

4. 静态方法中不能调用任何非静态方法，因为非静态方法有this参数，在静态方法中调用时候无法传递this引用
public static String getClassRoom(){
doClass();
return classRoom;
}

// 编译报错：Error:(35, 9) java: 无法从静态上下文中引用非静态 方法 doClass()
 */

//7.4static成员变量初始化
//注意：静态成员变量一般不会放在构造方法初始化，构造方法中初始化的是与对象相关的实例化属性


//静态成员变量的初始化分为两种：就地初始化和静态代码块初始化
//1. 就地初始化：就地初始化指的是：在定义的时候直接给出初始化
/*
public class Student{
    private String name;
    private String gender;
    private int age;
    private double score;
    private static String classRoom = "Bit306";

// ...
}
 */
//2.静态代码块初始化


